import copy
import numpy as np
from decimal import Decimal

from util.tool import get_index


# 计算下一个点的时间
def get_next_time(x1, y1, x2, y2, y3):
    """
    计算下一个点的时间
    :param x1:
    :param y1:
    :param x2:
    :param y2:
    :param y3:
    :return: x3, time3
    """
    if x2 - x1 == 0:
        result = y2
    else:
        result = (y3 - y1 + (y2 - y1) / (x2 - x1) * x1) * (x2 - x1) / (y2 - y1)
    # return float(result)  # 转换回浮点数
    return result


# 更新初至，间隔为10时使用
def update_time_10(time_origin, time, deep, start_idx, err=0.01, type=1):
    """
    更新初至，间隔为10时使用
    :param time_origin:
    :param time:
    :param deep:
    :param start_idx:
    :param err: 误差，默认为0.01
    :param type: 计算方法的类型
    :return: 当前使用的计算方法的类型
    """
    time3 = get_next_time(time[start_idx], deep[start_idx], time[start_idx + 1], deep[start_idx + 1],
                          deep[start_idx + 2])
    diff = time_origin[start_idx + 2] - time3

    # 计算误差向左还是向右
    if diff > 0:
        flag = Decimal(err)
    elif diff < 0:
        flag = Decimal(-err)
    else:
        res = time[start_idx - 1] - time[start_idx]
        flag = res / res * err

    # 更新初至
    if abs(diff) < 0.5 and type == 1:  # 方式1
        key = 1
        time[start_idx + 2] = time3 + flag
        print("type1_10")
    else:  # 方式2
        key = 2
        print("type2_10")
        time[start_idx + 1] = get_next_time(time[start_idx], deep[start_idx], time[start_idx + 2], deep[start_idx + 2],
                                            deep[start_idx + 1])
        time[start_idx] = get_next_time(time[start_idx - 1], deep[start_idx - 1], time[start_idx + 1],
                                        deep[start_idx + 1], deep[start_idx])
        time[start_idx - 1] = get_next_time(time[start_idx - 2], deep[start_idx - 2], time[start_idx], deep[start_idx],
                                            deep[start_idx - 1])
        time[start_idx] = get_next_time(time[start_idx - 1], deep[start_idx - 1], time[start_idx + 1],
                                        deep[start_idx + 1], deep[start_idx])
        time[start_idx + 1] = get_next_time(time[start_idx], deep[start_idx], time[start_idx + 2],
                                            deep[start_idx + 2], deep[start_idx + 1])
        time[start_idx + 2] = time_origin[start_idx + 2] + flag

    return key


# 更新初至，间隔为20时使用
def update_time_20(time_origin, time, deep, start_idx, err=0.01, type=1):
    """
    更新初至，间隔为20时使用
    :param time_origin:
    :param time:
    :param deep:
    :param start_idx:
    :param err: 误差，默认为0.01
    :param type: 计算方法的类型
    :return: 当前使用的计算方法的类型
    """
    time3 = get_next_time(time[start_idx], deep[start_idx], time[start_idx + 1], deep[start_idx + 1],
                          deep[start_idx + 2])
    diff = time_origin[start_idx + 2] - time3

    # 计算误差向左还是向右
    if diff > 0:
        flag = Decimal(err)
    elif diff < 0:
        flag = Decimal(-err)
    else:
        res = time[start_idx - 1] - time[start_idx]
        flag = res / res * err

    # 更新初至
    if abs(diff) < 0.5 and type == 1:  # 方式1
        key = 1
        time[start_idx + 2] = time3 + flag
        print("type1_20")
    else:  # 方式2
        key = 2
        print("type2_20")
        time[start_idx + 1] = get_next_time(time[start_idx], deep[start_idx], time[start_idx + 2], deep[start_idx + 2],
                                            deep[start_idx + 1])
        time[start_idx] = get_next_time(time[start_idx - 1], deep[start_idx - 1], time[start_idx + 1],
                                        deep[start_idx + 1], deep[start_idx])
        time[start_idx + 1] = get_next_time(time[start_idx], deep[start_idx], time_origin[start_idx + 2],
                                            deep[start_idx + 2],
                                            deep[start_idx + 1])
        time[start_idx + 2] = time_origin[start_idx + 2] + flag

    return key

# 计算初至
def cal_op(time_origin, deep_origin, deep_start, deep_end):
    """
    计算初至
    :param time_origin:
    :param deep_origin:
    :param deep_start:
    :param deep_end:
    :return: time，计算得到的初至
    """
    time = copy.deepcopy(time_origin)
    deep = copy.deepcopy(deep_origin)
    start_idx = get_index(np.array(deep), deep_start)
    end_idx = get_index(np.array(deep), deep_end)
    print(start_idx, end_idx)

    # 计算深度间隔
    deep_diff = []
    for i in range(len(deep)):
        if i == 0:
            deep_diff.append(0)
        else:
            deep_diff.append(deep[i] - deep[i - 1])
    deep_diff[0] = deep_diff[1]

    modified_direct = 0  # 方向修正
    type = 1
    while start_idx <= end_idx and start_idx <= len(deep_diff) - 3:
        if deep_diff[start_idx] == 20:  # 深度间隔为20
            key = update_time_20(time_origin, time, deep, start_idx, 0.04, type)  # 更新初至时间
        else:
            key = update_time_10(time_origin, time, deep, start_idx, 0.007, type)  # 更新初至时间

        # 计算某一种计算方式的连续使用次数
        if modified_direct > 0:  # 方式1
            if key == 1:  # 此次使用方式1
                modified_direct = modified_direct + 1
            else:
                modified_direct = 0
        elif modified_direct < 0:  # 方式2
            if key == 1:  # 此次使用方式1
                modified_direct = 0
            else:
                modified_direct = modified_direct - 1
        else:
            if key == 1:
                modified_direct = modified_direct + 1
            else:
                modified_direct = modified_direct - 1

        # 对连续使用次数进行限制
        if modified_direct == 3:
            modified_direct = 0
            type = 2
        elif modified_direct == -3:
            modified_direct = 0
            type = 1

        start_idx = start_idx + 1

    # 最后一个点
    time[start_idx + 1] = get_next_time(time[start_idx - 1], deep[start_idx - 1], time[start_idx], deep[start_idx],
                                        deep[start_idx + 1])

    return time